/*
 ============================================================================
 Name		: TetrisGameAppUi.cpp
 Author	  : Vladimir Hozjan
 Copyright   : Copyright (C) 2008 Vladimir Hozjan <vladimir.hozjan@gmail.com>
 Description : CTetrisGameAppUi implementation
 ============================================================================
 */

// INCLUDE FILES
#include <avkon.hrh>
#include <aknmessagequerydialog.h>
#include <aknnotewrappers.h>
#include <stringloader.h>
#include <hlplch.h>
#include <e32base.h>
#include <e32math.h> 
 
#include <TetrisGame_0xE0F9F2B6.rsg>

#include "TetrisGame_0xE0F9F2B6.hlp.hrh"
#include "TetrisGame.hrh"
#include "TetrisGame.pan"
#include "TetrisGameApplication.h"
#include "TetrisGameAppUi.h"
#include "TetrisGameAppView.h"
#include "Tetris.h"

/**
 * @class TestRandomImpl
 * 
 * Null random implementation of random interface
 *
 * @author VHOZ
 *
 * @remarks VHOZ [25.12.2008]: Class created
 */
class SystemImpl : public SystemInterface {
public:
  /// Constructor
	SystemImpl(){};

  /// Destructor
  virtual ~SystemImpl(){};

  /// return random number
  virtual int getRandom(int aMaxValue) {
    TInt64 seed = User::TickCount();
    return (Math::Rand(seed) % aMaxValue);
  }
  
  virtual double sqrt(double aVal) {
    TReal64  retval;
    Math::Sqrt(retval, aVal);
    return retval;
  }
};

/*static null random object*/
static SystemImpl systemObject;

// ============================ MEMBER FUNCTIONS ===============================


// -----------------------------------------------------------------------------
// CTetrisGameAppUi::ConstructL()
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CTetrisGameAppUi::ConstructL()
	{
	// Initialise app UI with standard value.
	BaseConstructL(CAknAppUi::EAknEnableSkin);

	// Create view object
	iAppView = CTetrisGameAppView::NewL(ClientRect());

    AddToStackL(iAppView);      //add view object onto stack

    // Initialize iTetris
	iTetris = NULL;
	
	}
// -----------------------------------------------------------------------------
// CTetrisGameAppUi::CTetrisGameAppUi()
// C++ default constructor can NOT contain any code, that might leave.
// -----------------------------------------------------------------------------
//
CTetrisGameAppUi::CTetrisGameAppUi()
	{
	// No implementation required
	}

// -----------------------------------------------------------------------------
// CTetrisGameAppUi::~CTetrisGameAppUi()
// Destructor.
// -----------------------------------------------------------------------------
//
CTetrisGameAppUi::~CTetrisGameAppUi()
	{
	if (iAppView)
		{
		RemoveFromStack( iAppView );
		delete iAppView;
		iAppView = NULL;
		}
	if (iTetris)
		{
		delete iTetris;
		iTetris = NULL;
		}
	if (iTimer) 
		{
	    iTimer->Cancel();
		delete iTimer;
	    iTimer = NULL;
		}
	}

// -----------------------------------------------------------------------------
// CTetrisGameAppUi::HandleCommandL()
// Takes care of command handling.
// -----------------------------------------------------------------------------
//
void CTetrisGameAppUi::HandleCommandL(TInt aCommand)
	{
	switch (aCommand)
		{
		case EEikCmdExit:
		case EAknSoftkeyExit:
			Exit();
			break;

		case ENewGame:
			{
			
			onNewGame();
			}
			break;
		case EHelp:
			{

			CArrayFix<TCoeHelpContext>* buf = CCoeAppUi::AppHelpContextL();
			HlpLauncher::LaunchHelpApplicationL(iEikonEnv->WsSession(), buf);
			}
			break;
		case EAbout:
			{

			CAknMessageQueryDialog* dlg = new (ELeave) CAknMessageQueryDialog();
			dlg->PrepareLC(R_ABOUT_QUERY_DIALOG);
			HBufC* title = iEikonEnv->AllocReadResourceLC(R_ABOUT_DIALOG_TITLE);
			dlg->QueryHeading()->SetTextL(*title);
			CleanupStack::PopAndDestroy(); //title
			HBufC* msg = iEikonEnv->AllocReadResourceLC(R_ABOUT_DIALOG_TEXT);
			dlg->SetMessageTextL(*msg);
			CleanupStack::PopAndDestroy(); //msg
			dlg->RunLD();
			}
			break;
		default:
			Panic(ETetrisGameUi);
			break;
		}
	}
// -----------------------------------------------------------------------------
//  Called by the framework when the application status pane
//  size is changed.  Passes the new client rectangle to the
//  AppView
// -----------------------------------------------------------------------------
//
void CTetrisGameAppUi::HandleStatusPaneSizeChange()
	{
	iAppView->SetRect(ClientRect());
	}

CArrayFix<TCoeHelpContext>* CTetrisGameAppUi::HelpContextL() const
	{
#warning "Please see comment about help and UID3..."
	// Note: Help will not work if the application uid3 is not in the
	// protected range.  The default uid3 range for projects created
	// from this template (0xE0000000 - 0xEFFFFFFF) are not in the protected range so that they
	// can be self signed and installed on the device during testing.
	// Once you get your official uid3 from Symbian Ltd. and find/replace
	// all occurrences of uid3 in your project, the context help will
	// work. Alternatively, a patch now exists for the versions of 
	// HTML help compiler in SDKs and can be found here along with an FAQ:
	// http://www3.symbian.com/faq.nsf/AllByDate/E9DF3257FD565A658025733900805EA2?OpenDocument
	CArrayFixFlat<TCoeHelpContext>* array = new (ELeave) CArrayFixFlat<
			TCoeHelpContext> (1);
	CleanupStack::PushL(array);
	array->AppendL(TCoeHelpContext(KUidTetrisGameApp, KGeneral_Information));
	CleanupStack::Pop(array);
	return array;
	}

void CTetrisGameAppUi::onNewGame()
{
	if (iTetris)
		{
		delete iTetris;
		iTetris = NULL;
		}
	if (iTimer) 
		{
	    iTimer->Cancel();
		delete iTimer;
	    iTimer = NULL;
		}
	
	iTetris = new Tetris(systemObject);
	TTetrisFunctor<CTetrisGameAppUi> positionCallback(this,&CTetrisGameAppUi::onTetrisChange);
	TTetrisFunctor<CTetrisGameAppUi> elementCallback(this,&CTetrisGameAppUi::onTetrisElementChange);
	iTetris->setPositionChangeCallback(positionCallback);
	iTetris->setElementChangeCallback(elementCallback);
	iAppView->setTetris(iTetris);

	iTimer = CPeriodic::NewL(0); // neutral priority
    iDelay = iTetris->getDelay() * 1000;   
	iTimer->Start(iDelay,iDelay,TCallBack(Tick, this));
}

TInt CTetrisGameAppUi::Tick(TAny* aObject)
    {
    // cast, and call non-static function
    ((CTetrisGameAppUi*)aObject)->doTick();
    return 1;
    }

void CTetrisGameAppUi::doTick()
	{
    iTetris->moveDown();
	TInt delay = iTetris->getDelay() * 1000;
	if (iDelay != delay)
		{
        iTimer->Cancel();
        iDelay = delay;
    	iTimer->Start(iDelay,iDelay,TCallBack(Tick, this));
		}
	}

void CTetrisGameAppUi::onTetrisChange()
	{
    iAppView->DrawToBackBuffer();  
	iAppView->DrawNow();
	}

void CTetrisGameAppUi::onTetrisElementChange()
	{

	}

// End of File
